package server.response;

import server.constant.HttpContentType;
import server.constant.HttpStatusCode;
import server.resolver.resource.DefaultResourceResolver;
import server.resolver.suffix.SuffixResolver;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author cg
 * @date 2023/6/7 13:38
 */
public class HttpResponse {
    private OutputStream outputStream;


    private Map<String, String> cookieMap = new HashMap<>();
    public HttpResponse(OutputStream outputStream) {
        this.outputStream = outputStream;
    }
    /**
     * 采用默认的请求头实时发送响应数据
     * @param text 响应数据
     * @throws IOException
     */
    public void writeAndFlush(String text) {
        try {
            ResponseHeader responseHeader = new ResponseHeader.Builder()
                    .statusCode(HttpStatusCode.SUCCESS)
                    .contentType(HttpContentType.TEXT)
                    .contentLength(String.valueOf(text.getBytes(StandardCharsets.UTF_8).length))
                    .setCookie(cookieMap)
                    .build();
            String response = responseHeader.toString()  + text;
            outputStream.write(response.getBytes(StandardCharsets.UTF_8));
            this.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 需要自己拼接响应头
     * @param text
     * @throws IOException
     */
    public void write(String text) {
        try {
            outputStream.write(text.getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void flush()  {
        try {
            outputStream.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void write404() {
        try {
            String text = "<h1>404 not found</h1>";
            ResponseHeader responseHeader = new ResponseHeader.Builder()
                    .statusCode(HttpStatusCode.NOTFOUND)
                    .contentType(HttpContentType.TEXT)
                    .contentLength(String.valueOf(text.getBytes(StandardCharsets.UTF_8).length))
                    .build();
            String response = responseHeader.toString() + text;
            outputStream.write(response.getBytes(StandardCharsets.UTF_8));
            this.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void write500() {
        try {
            String text = "<h1>500 Exception</h1>";
            ResponseHeader responseHeader = new ResponseHeader.Builder()
                    .statusCode(HttpStatusCode.NOTFOUND)
                    .contentType(HttpContentType.TEXT)
                    .contentLength(String.valueOf(text.getBytes(StandardCharsets.UTF_8).length))
                    .build();
            String response = responseHeader.toString() + text;
            outputStream.write(response.getBytes(StandardCharsets.UTF_8));
            this.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 返回请求静态资源
     * @param url 请求路径
     */
    public void writeResource(String url) throws IOException {
        //获取文件真实路径
        String path = this.getClass().getResource("/").getPath() + url;
        //判断是否存在该文件
        File file = new File(path);
        if (file.exists() && file.isFile()) {
            String suffix = path.substring(path.lastIndexOf('.'));
            //解析文件
            DefaultResourceResolver defaultResourceResolver = DefaultResourceResolver.getInstance();
            defaultResourceResolver.resolve(file, this, SuffixResolver.suffixResolver(suffix));
        }else {
            write404();
        }
    }

    public void setCookie(String key, String value) {
        this.cookieMap.put(key, value);
    }

    public void removeCookie(String key) {
        this.cookieMap.remove(key);
    }
    public OutputStream getOutputStream() {
        return outputStream;
    }

    public void setOutputStream(OutputStream outputStream) {
        this.outputStream = outputStream;
    }
}
